﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using OT.Data;
using OT.Areas.Admin.Models;
using PagedList;
namespace OT.Areas.Student.Controllers
{
    public class MyTestController : Controller
    {
        #region Declaration
        readonly OTEntitiesme OTDb = new OTEntitiesme();
        int LanguageID = Utilities.GetLanguageID();
        #endregion

        #region Index
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public JsonResult Index(int pageNumber, int pageSize, string searchString, int pgindex, string columnFilter)
        {
            var Test = (List<Tests>)null;
            int recount = 0;
            try
            {
                int UserID = 0;
                if (Request.Cookies["LoginSesID"] != null)
                {
                    UserID = Convert.ToInt16(Request.Cookies["LoginSesID"].Value);
                }
                else
                {
                    TempData["notice"] = "Time Out ,Please Login";
                    Response.Redirect("~/Home");
                }

                Test = (from c in OTDb.Tests
                        join ttyp in OTDb.TestTypes
                       on c.TestTypeID equals ttyp.TestTypeID into output
                        join top in OTDb.Topics
                         on c.TopicID equals top.TopicID
                        join usr in OTDb.Users
                        on c.UserID equals usr.UserID
                        join sub in OTDb.Subjects
                       on c.SubjectID equals sub.SubjectID
                        from j in output.DefaultIfEmpty()
                        where c.UserID == UserID
                        where c.LanguageID == LanguageID
                        select new Tests
                        {
                            TestID = c.TestID,
                            TestName = c.TestName,
                            Description = c.Description,
                            TotalQuestion = (int)c.TotalQuestion,
                            CategoryName = c.Category.CategoryName,
                            Duration = (int)c.Duration,
                            PassingScore = (byte)c.PassingScore,
                            PositiveMark = (byte)c.PositiveMark,
                            NegativeMark = (byte)c.NegativeMark,
                            TopicName = top.TopicName,
                            CategoryID = c.CategoryID.Value,
                            Subject = sub.SubjectName,
                            TestType1 = j.TestType1,
                            CreatedDate = (DateTime)c.CreatedDate,
                            UpdatedDate = (DateTime)c.UpdatedDate,
                            noofatmpt =  OTDb.AttemptMsts.Where(a => a.TestID.Value.Equals(c.TestID)).Count<AttemptMst>(),
                            Status = (bool)c.Status,
                        }
                      ).ToList();

                if (!String.IsNullOrEmpty(searchString))
                    Test = Test.Where(r => r.TestName.Contains(searchString)).ToList();
                recount = Test.Count;
                Test = Test.Skip<Tests>(pgindex * (pageNumber - 1))
                    .Take<Tests>(pgindex).ToList<Tests>();
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return Json(new
            {
                PageNumber = pageNumber,
                PageSize = pageSize,
                PgIndex = pgindex,
                Data = Test,
                RecordCount = recount
            });
        }
        #endregion

        #region Create
        public ActionResult Create()
        {
            Tests Test = null;
            try
            {
                Test = new Tests();
                var tt = OTDb.TestTypes.ToList();
                Test.TestTypes = tt;
                var top = OTDb.Topics.Where(t=>t.Status==true).ToList();
                Test.Topics = top;
                var cat = OTDb.Categories.Where(c=>c.Status==true).ToList();
                Test.cat = cat;
                var Sub = OTDb.Subjects.Where(s=>s.Status==true).ToList();
                Test.Subjects = Sub;
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return PartialView(Test);
        }
        [HttpPost]
        public string Create(string TestName, int TestTypeID, int CategoryID, int SubjectID, int TopicID, string Description, int TotalQuestion, int Duration, byte PassingScore, byte PositiveMark, byte NegativeMark, bool Status, string QuestionIDs)
        {
            string result = "";
            TestUser user = null;
            Test Test = null;
            TestQuestion TestQuestion = null;
            try
            {
                if (ModelState.IsValid)
                {
                    int UserID =Convert.ToInt16(Request.Cookies["LoginSesID"].Value);
                    Test = new Test();
                    Test.TestName = TestName;
                    Test.Description = Description;
                    Test.TotalQuestion = TotalQuestion;
                    Test.Duration = Duration;
                    Test.PassingScore = PassingScore;
                    Test.PositiveMark = PositiveMark;
                    Test.NegativeMark = NegativeMark;
                    Test.Status = Status;
                    if (TestTypeID != 0)
                        Test.TestTypeID = TestTypeID;
                    if (SubjectID != 0)
                        Test.SubjectID = SubjectID;
                    if (TopicID != 0)
                        Test.TopicID = TopicID;
                    Test.CategoryID = CategoryID;
                    Test.SubjectID = SubjectID;
                    Test.TopicID = TopicID;
                    Test.UserID = UserID;
                    Test.CreatedDate = DateTime.Now;
                    Test.UpdatedDate = DateTime.Now;
                    Test.LanguageID = LanguageID;
                    OTDb.Tests.Add(Test);
                    OTDb.SaveChanges();
                    if (string.IsNullOrEmpty(QuestionIDs))
                    {
                        var ql = OTDb.Questions.Where(r => r.SubjectID == SubjectID && r.TopicID == TopicID).ToList();
                        int cnt = 0;
                        foreach (Question drq in ql)
                        {
                            if (cnt < TotalQuestion)
                            {
                                TestQuestion = new TestQuestion();
                                TestQuestion.QuestionID = drq.QuestionID;
                                TestQuestion.TestID = Test.TestID;
                                OTDb.TestQuestions.Add(TestQuestion);
                                OTDb.SaveChanges();
                            }
                            cnt++;
                        }
                    }
                    else
                    {
                        string[] sep = { "," };
                        string[] IDs = QuestionIDs.Split(sep, StringSplitOptions.RemoveEmptyEntries);
                        List<int> ids = new List<int>();
                        foreach (var id in IDs)
                            ids.Add(Convert.ToInt32(id));
                        foreach (int QuestionID in ids)
                        {
                            TestQuestion = new TestQuestion();
                            TestQuestion.QuestionID = QuestionID;
                            TestQuestion.TestID = Test.TestID;
                            OTDb.TestQuestions.Add(TestQuestion);
                            OTDb.SaveChanges();
                        }
                    }
                    user = new TestUser();
                    user.UserID = UserID;
                    user.TestID = Test.TestID;
                    OTDb.TestUsers.Add(user);
                    OTDb.SaveChanges();
                    result = "Success";
                }
                else
                {
                    result = "NotValid";
                }
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return result;
        }
        #endregion

        #region Edit
        public ActionResult Edit(int TestID)
        {
            Tests Tests = null;
            try
            {
                var tst = OTDb.Tests.Where(r => r.TestID == TestID).SingleOrDefault();
                if (tst != null)
                {
                    Tests = new Tests();
                    Tests.TestID = tst.TestID;
                    Tests.TestName = tst.TestName;
                    Tests.Description = tst.Description;
                    var Questionslist = OTDb.TestQuestions.Where(r => r.TestID.Value.Equals(tst.TestID)).ToList();
                    if (Questionslist != null)
                    {
                        Tests.totalAvailQue = Questionslist.Count;
                    }
                    string res = GetAvailableQuestion((int)tst.SubjectID, (int)tst.TopicID);
                    Tests.totalAvailQue = Convert.ToInt16(res);
                    Tests.Status = (bool)tst.Status;
                    if (tst.TestTypeID != null)
                        Tests.TestTypeID = (int)tst.TestTypeID;
                    if (tst.SubjectID != null)
                        Tests.SubjectID = (int)tst.SubjectID;
                    if (tst.TopicID != null)
                        Tests.TopicID = (int)tst.TopicID;
                    Tests.TotalQuestion = Questionslist.Count;
                    Tests.Duration = (int)tst.Duration;
                    Tests.PassingScore = (byte)tst.PassingScore;
                    Tests.PositiveMark = (byte)tst.PositiveMark;
                    Tests.NegativeMark = (byte)tst.NegativeMark;
                    Tests.SubjectID = (int)tst.SubjectID;
                    Tests.TopicID = (int)tst.TopicID;
                    Tests.CategoryID = tst.CategoryID.Value;
                    var top = OTDb.Topics.Where(t => t.SubjectID.Value.Equals(tst.SubjectID.Value)).ToList();
                    Tests.Topics = top;
                    var sub = OTDb.Subjects.Where(s => s.CategoryID.Value.Equals(tst.CategoryID.Value)).ToList();
                    Tests.Subjects = sub;
                    var category = OTDb.TestTypes.ToList();
                    Tests.TestTypes = category;
                    var cat = OTDb.Categories.ToList();
                    Tests.cat = cat;
                }
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return PartialView(Tests);
        }
        [HttpPost]
        public string Edit(int TestID, string TestName, int TestTypeID, int CategoryID, int SubjectID, int TopicID, string Description, int TotalQuestion, int Duration, byte PassingScore, byte PositiveMark, byte NegativeMark, string QuestionIDs)
        {
            string result = "";
            TestQuestion TestQuestion = null;
            try
            {
                if (ModelState.IsValid)
                {
                    var category = OTDb.Tests.Where(r => r.TestID == TestID).SingleOrDefault();
                    if (category != null)
                    {
                        category.TestName = TestName;
                        category.Description = Description;
                        category.Duration = Duration;
                        category.TotalQuestion = TotalQuestion;
                        category.PassingScore = PassingScore;
                        category.PositiveMark = PositiveMark;
                        category.NegativeMark = NegativeMark;
                        category.UpdatedDate = DateTime.Now;
                      
                        if (TestTypeID != 0)
                            category.TestTypeID = TestTypeID;
                        if (CategoryID != 0)
                            category.CategoryID = CategoryID;
                        if (TopicID != 0)
                            category.TopicID = TopicID;
                        if (SubjectID != 0)
                            category.SubjectID = SubjectID;
                      
                        if (string.IsNullOrEmpty(QuestionIDs))
                        {
                            var ql = OTDb.Questions.Where(r => r.SubjectID == SubjectID && r.TopicID == TopicID && r.Status==true).ToList();
                            int cnt = 0;
                            foreach (Question drq in ql)
                            {
                                if (cnt < TotalQuestion)
                                {
                                    if (!IsTestQuestionExist(TestID, drq.QuestionID, CategoryID))
                                    {
                                        TestQuestion = new TestQuestion();
                                        TestQuestion.QuestionID = drq.QuestionID;
                                        TestQuestion.TestID = TestID;
                                        OTDb.TestQuestions.Add(TestQuestion);
                                        OTDb.SaveChanges();
                                    }
                                }
                                cnt++;
                            }
                        }
                        else
                        {
                            string[] sep = { "," };
                            string[] IDs = QuestionIDs.Split(sep, StringSplitOptions.RemoveEmptyEntries);
                            List<int> ids = new List<int>();
                            foreach (var id in IDs)
                                ids.Add(Convert.ToInt32(id));
                            List<TestQuestion> test = OTDb.TestQuestions.Where(t => t.TestID.Value.Equals(TestID)).ToList();
                            foreach (TestQuestion tst in test)
                            {
                                OTDb.TestQuestions.Remove(tst);
                                OTDb.SaveChanges();
                            }
                            foreach (int QuestionID in ids)
                            {
                                if (CategoryID != 0)
                                    category.CategoryID = CategoryID;
                                TestQuestion = new TestQuestion();
                                TestQuestion.QuestionID = QuestionID;
                                TestQuestion.TestID = TestID;
                                OTDb.TestQuestions.Add(TestQuestion);
                                OTDb.SaveChanges();
                            }
                        }
                        result = "Success";
                    }
                }
                else
                {
                    result = "NotValid";
                }
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
                result = "NotValid";
            }
            return result;
        }
        #endregion

        #region Delete
        public ActionResult Delete(int TestID)
        {
            Tests Tests = null;
            try
            {
                var tast = OTDb.Tests.Where(r => r.TestID == TestID).SingleOrDefault();
                if (tast != null)
                {
                    Tests = new Tests();

                    Tests.TestID = tast.TestID;
                    Tests.TestName = tast.TestName;
                    Tests.Description = tast.Description;
                    Tests.Status = (bool)tast.Status;
                    Tests.TotalQuestion = (int)tast.TotalQuestion;
                    Tests.Duration = (int)tast.Duration;
                    Tests.PassingScore = (byte)tast.PassingScore;
                    Tests.PositiveMark = (byte)tast.PositiveMark;
                    Tests.NegativeMark = (byte)tast.NegativeMark;
                    Tests.SubjectID = (int)tast.SubjectID;
                    Tests.TopicID = (int)tast.TopicID;
                    if (tast.SubjectID != null)
                        Tests.SubjectID = (int)tast.SubjectID;
                    if (tast.TopicID != null)
                        Tests.TopicID = (int)tast.TopicID;
                    if (tast.TestTypeID != null)
                        Tests.TestTypeID = (int)tast.TestTypeID;
                    var top = OTDb.Topics.ToList();
                    Tests.Topics = top;
                    var sub = OTDb.Subjects.ToList();
                    Tests.Subjects = sub;
                    var category = OTDb.TestTypes.ToList();
                    Tests.TestTypes = category;
                }
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return PartialView(Tests);
        }

        [HttpPost]
        public string Delete(int TestID, string IsDelete)
        {
            string result = "";
            try
            {
                var Tst = OTDb.Tests.Where(r => r.TestID == TestID).SingleOrDefault();
                if (Tst != null)
                {
                    OTDb.Tests.Remove(Tst);
                    OTDb.SaveChanges();
                    result = "Success";
                }
                else { result = "NotValid"; }
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
                result = "NotValid";
            }
            return result;
        }
        #endregion

        #region JsonCall
        [AcceptVerbs(HttpVerbs.Get)]
        public JsonResult Subjects(int CategoryID)
        {
            var subjectList = (List<Subject>)null;
            subjectList = OTDb.Subjects.Where(sub => sub.CategoryID.Value.Equals(CategoryID)).ToList();
            var stateData = subjectList.Select(m => new SelectListItem()
             {
                 Text = m.SubjectName,
                 Value = m.SubjectID.ToString(),
             });
            return Json(stateData, JsonRequestBehavior.AllowGet);
        }

        [AcceptVerbs(HttpVerbs.Get)]
        public JsonResult Topics(int SubjectID)
        {
            var subjectList = (List<Topic>)null;
            subjectList = OTDb.Topics.Where(sub => sub.SubjectID.Value.Equals(SubjectID)).ToList();
            var stateData = subjectList.Select(m => new SelectListItem()
            {
                Text = m.TopicName,
                Value = m.TopicID.ToString(),
            });
            return Json(stateData, JsonRequestBehavior.AllowGet);
        }
        public string GetAvailableQuestion(int SubjectID, int TopicID)
        {
            string response = string.Empty;
            try
            {
                var Questionslist = OTDb.Questions.Where(r => r.SubjectID.Value == SubjectID && r.TopicID.Value == TopicID && r.Status == true).ToList();
                if (Questionslist != null)
                {
                    response = Questionslist.Count.ToString();
                }
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return response;
        }
        public bool IsTestQuestionExist(int TestID, int QuestionID, int CategoryID)
        {
            bool response = false;
            try
            {
                var Questionslist = OTDb.TestQuestions.Where(r => r.TestID.Value == TestID && r.QuestionID.Value == QuestionID).ToList();
                if (Questionslist.Count != 0)
                {
                    response = true;
                }
                List<TestQuestion> TestQuestion = OTDb.TestQuestions.Where(r => r.TestID.Value == TestID).ToList();
                foreach (TestQuestion tst in TestQuestion)
                {
                    if (!tst.Test.CategoryID.Value.Equals(CategoryID))
                    {
                        OTDb.TestQuestions.Remove(tst);
                        OTDb.SaveChanges();
                    }
                }

            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return response;
        }

        public static List<SelctedQuestionList_Result> data1obj;
        public ActionResult ShowAllQuestion(int subjectId, int topicid, int testid)
        {
            data1obj = OTDb.SelctedQuestionList(subjectId, topicid, testid).ToList<SelctedQuestionList_Result>();
            return PartialView(data1obj.ToPagedList(1, 1000));
        }
        public ActionResult ShowAllQuestionCreate(int subjectId, int topicid)
        {
            var Questionslist = (List<Question>)null;
            Questionslist = (from c in OTDb.Questions
                             where c.SubjectID.Value.Equals(subjectId) && c.TopicID.Value.Equals(topicid) && c.Status==true
                             select c).ToList();

            return PartialView(Questionslist.ToPagedList(1, 1000));
        }
        #endregion
    }
}
